package yl.hs.bmipfull.controllers.finance;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import yl.hs.bmipfull.controllers.ControllerBase;
import yl.hs.bmipfull.service.finance.IShipSettleService;
import yl.hs.bmipfull.service.system.ISearchViewService;
import yl.hs.bmipfull.utils.ExcelMapUtil;
import yl.hs.bmipfull.viewmodels.PageQuery;
import yl.hs.bmipfull.viewmodels.SubmitModel;
import yl.hs.bmipfull.viewmodels.WebResult;
import yl.hs.bmipfull.viewmodels.system.ExcelMap;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/*
 * ShipSettleController 发货结算控制器
 *
 * @author 谢景广
 * @category 财务管理——发货结算
 * @date 2021-12-29
 */
@Api(value = "发货结算操作数据接口", tags = "财务管理——发货结算")
@RequestMapping(path = "/api/finance/shipSettle")
@RestController
public class ShipSettleController extends ControllerBase {

    @Value("${template.shipOrder.Excel}")
    private String tmpPath;

    @ApiOperation(value = "结算单查询数据接口", notes = "查询结算单")
    @RequestMapping(path = {"/{rowNum}", "/{rowNum}/{page}"}, method = RequestMethod.POST)
    public WebResult querySettlePage(@RequestBody PageQuery query, @ApiParam("页面大小，为0时没有分页的临时数据，否则为正式结算单") @PathVariable int rowNum, @PathVariable(required = false) int page) {
        try {
            var result = settleSvc.queryPage(query, rowNum, page);
            svSVC.updateUserMenuView(query);
            return success("ok", result);
        } catch (Exception ee) {
            return error(ee);
        }
    }

    @ApiOperation(value = "结算单详情数据接口", notes = "查询结算单明细和附加项")
    @GetMapping(path = "/Details/{settleSN}")
    public WebResult findDetailsBySN(@ApiParam("结算单标识") @PathVariable String settleSN) {
        try {
            var result = settleSvc.querySettleDetailsBySettleSN(settleSN);
            return success("ok", result);
        } catch (Exception ee) {
            return error(ee);
        }
    }

    @ApiOperation(value = "结算单详情数据接口", notes = "查询结算单明细和附加项")
    @RequestMapping(path = "/Temp/{contractSN}/{productCateSN}/{startDate}/{endDate}", method = RequestMethod.GET)
    public WebResult findDetailsBySearch(@ApiParam("合同标识") @PathVariable String contractSN,
                                         @ApiParam("产品类别编号") @PathVariable String productCateSN,
                                         @ApiParam("发货开始日期") @PathVariable String startDate,
                                         @ApiParam("发货结束日期") @PathVariable String endDate) {
        try {
            var result = settleSvc.queryTempSettleDetails(contractSN, productCateSN, startDate, endDate);
            return success("ok", result);
        } catch (Exception ee) {
            return error(ee);
        }
    }

    @ApiOperation(value = "结算单对账单数据接口", notes = "结算单对账单数据接口")
    @RequestMapping(path = "/orders/{contractSN}/{productCateSN}/{startDate}/{endDate}", method = RequestMethod.GET)
    public WebResult findOrdersBySearch(@ApiParam("合同标识") @PathVariable String contractSN,
                                        @ApiParam("产品类别编号") @PathVariable String productCateSN,
                                        @ApiParam("发货开始日期") @PathVariable String startDate,
                                        @ApiParam("发货结束日期") @PathVariable String endDate) {
        try {
            var result = settleSvc.queryOrdersSettleDetails(contractSN, productCateSN, startDate, endDate);
            return success("ok", result);
        } catch (Exception ee) {
            return error(ee);
        }
    }

    @ApiOperation(value = "结算单取消审核并删除结算信息接口", notes = "结算单取消审核并删除结算信息")
    @RequestMapping(path = "/cancel/{settleSN}", method = RequestMethod.DELETE)
    public WebResult cancelSettle(@ApiParam("结算单标识") @PathVariable String settleSN) {
        try {
            var result = settleSvc.cancelSettle(settleSN);
            if (result > 0) {
                return success("ok");
            } else {
                return fail("取消失败");
            }
        } catch (Exception ee) {
            return error(ee);
        }
    }

    @ApiOperation(value = "保存并审核结算单接口", notes = "保存并审核结算单接口")
    @RequestMapping(path = "/save", method = RequestMethod.POST)
    public WebResult saveSettle(@ApiParam(value = "提交的结算信息") @RequestBody SubmitModel submitModel) {
        try {
            var result = settleSvc.saveSettle(submitModel);
            if (result > 0) {
                return success("审核成功");
            } else {
                return fail("审核失败");
            }
        } catch (Exception ee) {
            return error(ee);
        }
    }

    @ApiOperation(value = "结算单详情数据接口", notes = "查询结算单明细和附加项")
    @RequestMapping(path = "/orders/{settleSN}", method = RequestMethod.GET)
    public WebResult querySettleOrders(@ApiParam("结算单标识") @PathVariable String settleSN) {
        try {
            var result = settleSvc.querySettleOrdersBySettleSN(settleSN);
            return success("ok", result);
        } catch (Exception ee) {
            return error(ee);
        }
    }

    @ApiOperation(value = "结算单详情数据接口", notes = "查询结算单明细和附加项")
    @RequestMapping(path = "/ordersBySNList/{snList}", method = RequestMethod.GET)
    public WebResult querySettleOrdersBySettleSN(@ApiParam("结算单标识") @PathVariable String snList) {
        try {
            var result = settleSvc.querySettleOrdersBySnList(snList);
            return success("ok", result);
        } catch (Exception ee) {
            return error(ee);
        }
    }

    @ApiOperation(value = "结算发货明细导出", notes = "结算发货明细导出")
    @RequestMapping(path = "/orderExport/{settleSN}", method = RequestMethod.GET)
    public void exportOrders(@ApiParam("结算单标识") @PathVariable String settleSN, HttpServletResponse response) {
        try {
            settleSvc.updateExportCount(settleSN);
            var orderList = settleSvc.queryExportOrdersBySettleSN(settleSN);
            List<ExcelMap> maps = new ArrayList<>();
            maps.add(new ExcelMap(0, "outTime", ""));
            maps.add(new ExcelMap(1, "sn", ""));
            maps.add(new ExcelMap(2, null, "15"));
            maps.add(new ExcelMap(3, null, "普通销售"));
            maps.add(new ExcelMap(4, null, "专用发票"));
            maps.add(new ExcelMap(6, null, "纸票"));
            maps.add(new ExcelMap(7, "customerSN", ""));
            maps.add(new ExcelMap(9, "customerSN", ""));
            maps.add(new ExcelMap(24, null, "其他"));
            maps.add(new ExcelMap(27, null, "销售出库"));
            maps.add(new ExcelMap(31, "remark", ""));
            maps.add(new ExcelMap(33, null, "02"));
            maps.add(new ExcelMap(35, "projectSN", ""));
            maps.add(new ExcelMap(39, "accountProductSN", ""));
            maps.add(new ExcelMap(42, "weight", ""));
            maps.add(new ExcelMap(44, null, 1.0D));
            maps.add(new ExcelMap(45, null, 0.13D));
            maps.add(new ExcelMap(46, "prices", ""));
            maps.add(new ExcelMap(47, "amount", ""));
            maps.add(new ExcelMap(48, null, "正常"));
            var util = new ExcelMapUtil("shipOrderTemp");
            response.reset();
            // 设置response的Header
            response.setCharacterEncoding("UTF-8");
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(settleSN + "产品发货单.xlsx", StandardCharsets.UTF_8));
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            var orderPath = tmpPath;
            var buffer = util.exportByTemplate(orderPath, 2, orderList, maps);//第三行
            response.addHeader("Content-Length", "" + buffer.length);
            outputStream.write(buffer);
            outputStream.flush();
        } catch (Exception ee) {
            log.error("导出错误", ee);
        }
    }

    @Autowired
    public void setSvSVC(ISearchViewService svSVC) {
        this.svSVC = svSVC;
    }

    @Autowired
    public void setSettleSvc(IShipSettleService settleSvc) {
        this.settleSvc = settleSvc;
    }

    ISearchViewService svSVC;

    IShipSettleService settleSvc;
}
